﻿// ******************************************************************************************************
// <copyright file="ModelCircular.cs" company="Caroso.inc">
//     Copyright (c) Carlos Osorio All rights reserved.
// </copyright>
// ******************************************************************************************************
// The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); 
// you may not use this file except in compliance with the License. You may obtain a copy of the License at 
// http:// www.mozilla.org/MPL/ 
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF 
// ANY KIND, either express or implied. See the License for the specificlanguage governing rights and 
// limitations under the License. 
// 
// The Original Code is this . mapWindow 
// 
// The Initial Developer of this version of the Original Code is Carlos Osorio carosocali@gmail.com
// 
// Contributor(s): (Open source contributors should list themselves and their modifications here). 
// Change Log: 
// Date           Changed By      Notes
// 22 Nov 2010    Carlos Osorio   Inital upload 
// ******************************************************************************************************

namespace GeostatisticalTool.Classes
{
    using System;

    /// <summary>
    /// Spherical Model 
    /// </summary> 
    public class ModelCircular : IKrigingModel
    {
        /// <summary>
        /// Define the range
        /// </summary>
        private double mrange = 1;

        /// <summary>
        /// Define the sill of the model
        /// </summary>
        private double msill = 0;

        /// <summary>
        /// Define the nugget of the model
        /// </summary>
        private double mnugget = 0;

        /// <summary>
        /// Gets or sets to define the Range
        /// </summary>
        public double Range
        {
            get
            {
                return this.mrange;
            }

            set
            {
                this.mrange = value;
            }
        }

        /// <summary>
        /// Gets or sets  the sill in the model
        /// </summary>
        public double C1
        {
            get
            {
                return this.msill;
            }

            set
            {
                this.msill = value;
            }
        }

        /// <summary>
        /// Gets or sets the nugget in the model
        /// </summary>
        public double C0
        {
            get
            {
                return this.mnugget;
            }

            set
            {
                this.mnugget = value;
            }
        }

        /// <summary>
        /// Gets the name 
        /// </summary>
        public string Name
        {
            get
            {
                return "Circular";
            }
        }

        /// <summary>
        /// Gets the name of the  model
        /// </summary>
        public Model ModelType
        {
            get
            {
                return Model.Circular;
            }
        }


        /// <summary>
        /// Obtain the value of the interpolation
        /// </summary>
        /// <param name="distance">Distance to be evaluated in the model</param>
        /// <returns>Value interpolated</returns>
        public double GetValue(double distance)
        {
            if (distance == 0)
               return this.mnugget;


            if (distance <= this.mrange && distance>0)
            {
                //return this.mnugget +
                //    this.msill * (1 -
                //                    ((2 / Math.PI) * (Math.Acos((distance / this.mrange)))) +
                //                    Math.Sqrt(1 -
                //                                   ((distance * distance) /
                //                                    (this.mrange * this.mrange)
                //                                   )
                //                              )
                //               );

               return this.mnugget + (((2 * this.msill) / Math.PI) * (((distance / this.mrange) * Math.Sqrt(1 - ((distance * distance) / (this.mrange * this.mrange)))) + Math.Asin(distance / this.mrange)));
            }
            else
            {
                return this.mnugget + this.msill;
            }
        }
    }
}
